package cn.stylefeng.guns.sys.modular.system.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.modular.system.db2.service.BusinessService;
import cn.stylefeng.guns.sys.modular.system.db5.service.UserDataService;
import cn.stylefeng.guns.sys.modular.system.model.params.ProDataViewParam;
import cn.stylefeng.guns.sys.modular.system.model.result.DataShopInfoResult;
import cn.stylefeng.guns.sys.modular.system.model.result.ShopDataResult;
import cn.stylefeng.guns.sys.modular.system.service.ProjectBusinessViewService;
import cn.stylefeng.guns.sys.modular.system.service.ProjectService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*;

import static java.util.stream.Collectors.toList;

@Controller
@RequestMapping("/gcBusinessView")
public class ProjectBusinessViewController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(ProjectBusinessViewController.class);
    @Autowired
    private ProjectBusinessViewService projectBusinessViewService;

    @Autowired
    private BusinessService businessService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private UserDataService userDataService;

    /**
     * 全部门店
     */
    @RequestMapping("/findAllShops")
    @ResponseBody
    public ResponseData findAllShops(HttpServletRequest request, ProDataViewParam param) {
        DataShopInfoResult dataInfoResult = new DataShopInfoResult();

        String mobile = request.getHeader("login_name");
        logger.info("营业分析-全部门店查询：{}，login_name:{}", param.toString(), mobile);

        List<Integer> allShopsByMobile = userDataService.findAllShopsByMobile(mobile);
        param.setParamList(allShopsByMobile);

        if (CollectionUtil.isNotEmpty(allShopsByMobile)) {
            logger.info("营业分析-全部门店查询：allShopsByMobile-{}", allShopsByMobile.toString());
        } else {
            logger.info("营业分析-全部门店查询：allShopsByMobile{}", "空");
        }

        if (CollectionUtil.isEmpty(allShopsByMobile)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, dataInfoResult);
        }


        List<Map<String, Object>> areaList = projectBusinessViewService.findAllShops(param);
        dataInfoResult.setTotal(areaList.size());
        dataInfoResult.setList(areaList);
//        //一周门店数
//        ProDataViewParam param2 = new ProDataViewParam();
//        param2.setParam(7);
//        List<Map<String, Object>> areaList2 = projectBusinessViewService.findAllShops(param2);
//        //二周门店数
//        ProDataViewParam param3 = new ProDataViewParam();
//        param3.setParam(14);
//        List<Map<String, Object>> areaList3 = projectBusinessViewService.findAllShops(param3);
//        //三周门店数
//        ProDataViewParam param4 = new ProDataViewParam();
//        param4.setParam(21);
//        List<Map<String, Object>> areaList4 = projectBusinessViewService.findAllShops(param4);
        //一月内开业门店数
        ProDataViewParam param5 = new ProDataViewParam();
        param5.setParam(30);
        param5.setParamList(allShopsByMobile);
        List<Map<String, Object>> fourWeek = projectBusinessViewService.findAllShops(param5);

        int one = 0;
        int two = 0;
        int three = 0;

        if (CollectionUtil.isNotEmpty(fourWeek)) {
            for (Map<String, Object> area : fourWeek) {
                int days = (int) area.get("days");

                if (0 <= days && days < 6) {
                    one = one + 1;
                }
                if (0 <= days && days < 13) {
                    two = two + 1;
                }
                if (0 <= days && days < 20) {
                    three = three + 1;
                }
            }
        }

        dataInfoResult.setNumOfOneWeek(one);
        dataInfoResult.setNumOfTwoWeek(two);
        dataInfoResult.setNumOfThreeWeek(three);
        dataInfoResult.setNumOfMonth(fourWeek.size());
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, dataInfoResult);
    }


    /**
     * 营业页签-营业收入（已结金额）、就餐人数、客单数
     */
    @RequestMapping("/findBusinessData")
    @ResponseBody
    public ResponseData findBusinessData(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-营业-营业收入、就餐人数、客单数查询参数：{}", param.toString());
        param.setType(null);

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //日期参数处理
        param.setStartTime(param.getDate().trim() + " 04:00:00");
        param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));

        return businessService.findBusinessData(param);
    }

    private void getShopIds(HttpServletRequest request, ProDataViewParam param) {
        String mobile = request.getHeader("login_name");
        //TODO 1.shopIds为空查的是全部门店 2.不为空时获取shopIdList参数
        if (StringUtils.isBlank(param.getShopIds())) {
            //30天之内开业的门店
            List<Integer> days30ShopIds = projectService.findBusinessShopIdsList();
            List<Integer> allShopsByMobile = userDataService.findAllShopsByMobile(mobile);
            if (days30ShopIds == null) {
                days30ShopIds = new ArrayList<>();
            }
            if (allShopsByMobile == null) {
                allShopsByMobile = new ArrayList<>();
            }
            List<Integer> finalAllShopsByMobile = allShopsByMobile;
            List<Integer> shopIds = days30ShopIds.stream().filter(item -> finalAllShopsByMobile.contains(item)).collect(toList());
            param.setParamList(shopIds);
        } else {
            String[] strArray = param.getShopIds().split(",");
            List<String> list = Arrays.asList(strArray);
            List<Integer> shopIdsList = list.stream().map(Integer::parseInt).collect(toList());
            param.setParamList(shopIdsList);
        }
    }


    /**
     * 堂食页签-营业收入（已结金额）、就餐人数、客单数
     */
    @RequestMapping("/findBusinessDataOfDineIn")
    @ResponseBody
    public ResponseData findBusinessDataOfDineIn(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-堂食-营业收入、就餐人数、客单数查询参数：{}", param.toString());

        //堂食
        param.setType(1);

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //日期参数处理
        param.setStartTime(param.getDate().trim() + " 04:00:00");
        param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));

        return businessService.findBusinessDataOfDineIn(param);
    }

    /**
     * 外卖页签-营业收入（已结金额）、就餐人数、客单数
     */
    @RequestMapping("/findBusinessDataOfTakeAway")
    @ResponseBody
    public ResponseData findBusinessDataOfTakeAway(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-堂食-营业收入、就餐人数、客单数查询参数：{}", param.toString());

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //日期参数处理
        param.setStartTime(param.getDate().trim() + " 04:00:00");
        param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));

        return businessService.findBusinessDataOfTakeAway(param);
    }


    /**
     * 近8天营业数据
     */
    @RequestMapping("/findRecentDaysBusinessData")
    @ResponseBody
    public ResponseData findRecentDaysBusinessData(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-近8天营业数据查询参数：{}", param.toString());

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //TODO 3.近8天数据
        if (param.getParam() == null || param.getParam() == 0) {
            return ResponseData.error(412, "请求失败，param参数不能为空");
        }

        LinkedHashMap<String, Object> map = businessService.findRecentDaysBusinessData(param);
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, map);
    }

    /**
     * 营业额排序
     */
    @RequestMapping("/findBusinessDataOrderByIncome")
    @ResponseBody
    public ResponseData findBusinessDataOrderByIncome(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-营业额排序查询参数：{}", param.toString());

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //TODO 3.取几条数据
        if (param.getLimit() == null || param.getLimit() == 0) {
            return ResponseData.error(412, "请求失败，数据条数不能为空");
        }

        //日期参数处理
        param.setStartTime(param.getDate().trim() + " 04:00:00");
        param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));
        List<Map<String, Object>> businessDataOrderByIncome = businessService.findBusinessDataOrderByIncome(param);
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome);
    }

    /**
     * 客流量排序
     */
    @RequestMapping("/findBusinessDataOrderByPeopleQty")
    @ResponseBody
    public ResponseData findBusinessDataOrderByPeopleQty(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-客流量排序查询参数：{}", param.toString());

        getShopIds(request, param);
        List<Integer> paramList = param.getParamList();
        if (CollectionUtil.isEmpty(paramList)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);
        }

        //TODO 2.日期参数处理
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }

        //TODO 3.取几条数据
        if (param.getLimit() == null || param.getLimit() == 0) {
            return ResponseData.error(412, "请求失败，数据条数不能为空");
        }

        //日期参数处理
        param.setStartTime(param.getDate().trim() + " 04:00:00");
        param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));
        List<Map<String, Object>> businessDataOrderByIncome = businessService.findBusinessDataOrderByPeopleQty(param);
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome);
    }


    /**
     * 新店首日数据-今日开业店
     */
    @RequestMapping("/findBusinessDataOfFirstDay")
    @ResponseBody
    public ResponseData findBusinessDataOfFirstDay(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-新店首日数据查询参数：{}", param.toString());

        //TODO 1.1门店参数处理
        getShopIds(request, param);

        //TODO 1开店首日及门店编号
        List<Map<String, Object>> shopInfoMapList = projectService.findBusinessShopList(param);

        //TODO 2.排序类型
        if (param.getType() == null || param.getType() == 0 && (param.getType() != 1 || param.getType() != 2)) {
            return ResponseData.error(412, "请求失败，排序类型不能为空");
        }

        if (CollectionUtil.isNotEmpty(shopInfoMapList)) {
            List<Map<String, Object>> businessDataOrderByIncome = businessService.findBusinessDataOfFirstDay(param, shopInfoMapList);
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome);
        }
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, null);


    }

    /**
     * 根据开业日期查询已经开业的门店
     */
    @RequestMapping("/findShops")
    @ResponseBody
    public ResponseData findShops(HttpServletRequest request, ProDataViewParam param) {

        String mobile = request.getHeader("login_name");
        //用户有权限查看的门店
        List<Integer> allShopsByMobile = userDataService.findAllShopsByMobile(mobile);
        param.setParamList(allShopsByMobile);

        if (CollectionUtil.isEmpty(allShopsByMobile)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, new ArrayList<Map<String, Object>>());
        }


        List<Map<String, Object>> areaList = projectBusinessViewService.findShopsByParam(param);
        //TODO 1.1日期参数处理-开始日期
        if (StringUtils.isBlank(param.getStartTime())) {
            return ResponseData.error(412, "请求失败，开始日期参数不能为空");
        }
        //TODO 1.2日期参数处理-截止日期
        if (StringUtils.isBlank(param.getEndTime())) {
            return ResponseData.error(412, "请求失败，结束日期参数不能为空");
        }
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, areaList);
    }

    /**
     * 查询门店收入
     */
    @RequestMapping("/findShopsIncome")
    @ResponseBody
    public ResponseData findShopsIncome(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-查询门店收入参数：{}", param.toString());


        //4个月前首日
        String firstDayOfMonthByParam = DateUtil.getFirstDayOfMonthByParam(4) + " 04:00:00";
        String firstDayOfMonthByParam2 = DateUtil.getFirstDayOfMonthByParam(1) + " 04:00:00";
        //上个月
        String lastMonthStr = DateUtil.getLastMonthStr();


        //TODO 1.1日期参数处理-开始日期
        if (StringUtils.isBlank(param.getStartTime())) {
            return ResponseData.error(412, "请求失败，开始日期参数不能为空");
        }
        //TODO 1.2日期参数处理-截止日期
        if (StringUtils.isBlank(param.getEndTime())) {
            return ResponseData.error(412, "请求失败，结束日期参数不能为空");
        }

        //TODO 1.3日期参数处理-月份
        if (StringUtils.isBlank(param.getMonthDate())) {
            return ResponseData.error(412, "请求失败，月份参数不能为空");
        }

        String mobile = request.getHeader("login_name");
        //用户有权限查看的门店
        List<Integer> allShopsByMobile = userDataService.findAllShopsByMobile(mobile);
        param.setParamList(allShopsByMobile);

        if (CollectionUtil.isEmpty(allShopsByMobile)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, new ArrayList<Map<String, Object>>());
        }

        //TODO 1.获取门店id
        List<Map<String, Object>> shops = projectBusinessViewService.findShopsByParam(param);
        List<Integer> shopIdList = new ArrayList<>();
        Map<Integer, String> shopMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(shops)) {
            for (Map<String, Object> shop : shops) {
                Integer shopId = Integer.parseInt(shop.get("shopId").toString());
                shopIdList.add(shopId);
                shopMap.put(shopId, shop.get("openDay").toString());
            }
        }
        param.setParamList(shopIdList);

        if (CollectionUtil.isNotEmpty(shopIdList)) {
            //TODO 2.参数处理-月份日期处理
            String month = param.getMonthDate();
            String fisrtDayOfMonth = DateUtil.getFisrtDayOfMonth(month);
            String lastDayOfMonth = DateUtil.getLastDayByMonth(month);

            param.setStartTime(fisrtDayOfMonth.trim() + " 04:00:00");
            param.setEndTime(DateUtil.get4OclockByDay(lastDayOfMonth.trim()));

            //TODO 3.获取查询结果
            //复用之前方法，补齐参数
            param.setLimit(10000);
            ShopDataResult shopDataResult = businessService.findBusinessDataWithIncomeTotalOrderByIncome(param);
            //TODO 4.加入开业日期
            if (CollectionUtil.isNotEmpty(shopDataResult.getList())) {
                for (Map<String, Object> map : shopDataResult.getList()) {
                    Integer shopId = Integer.parseInt(map.get("shopId").toString());
                    String openDay = shopMap.get(shopId);
                    map.put("openDay", openDay);
                }
            }

            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, shopDataResult);
        }
        ShopDataResult shopDataResult=new ShopDataResult();
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, shopDataResult);

    }


    /**
     * 查询门店收入
     */
    @RequestMapping("/findShopsIncomeByTimeScope")
    @ResponseBody
    public ResponseData findShopsIncomeByTimeScope(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-查询门店收入参数：{}", param.toString());

        //TODO 1.1日期参数处理-开始日期
        if (StringUtils.isBlank(param.getStartTime())) {
            return ResponseData.error(412, "请求失败，开始日期参数不能为空");
        }
        //TODO 1.2日期参数处理-截止日期
        if (StringUtils.isBlank(param.getEndTime())) {
            return ResponseData.error(412, "请求失败，结束日期参数不能为空");
        }

        String mobile = request.getHeader("login_name");
        //用户有权限查看的门店
        List<Integer> allShopsByMobile = userDataService.findAllShopsByMobile(mobile);
        param.setParamList(allShopsByMobile);

        if (CollectionUtil.isEmpty(allShopsByMobile)) {
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, new ArrayList<Map<String, Object>>());
        }

        //TODO 1.获取门店id
        List<Map<String, Object>> shops = projectBusinessViewService.findShopsByParam(param);
        List<Integer> shopIdList = new ArrayList<>();
        Map<Integer, String> shopMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(shops)) {
            for (Map<String, Object> shop : shops) {
                Integer shopId = Integer.parseInt(shop.get("shopId").toString());
                shopIdList.add(shopId);
                shopMap.put(shopId, shop.get("openDay").toString());
            }
        }
        param.setParamList(shopIdList);

        if (CollectionUtil.isNotEmpty(shopIdList)) {
            //TODO 2.参数处理-月份日期处理

            param.setStartTime(param.getStartTime().trim() + " 04:00:00");
            param.setEndTime(DateUtil.get4OclockByDay(param.getEndTime().trim()));

            //TODO 3.获取查询结果
            //复用之前方法，补齐参数
            param.setLimit(10000);
            ShopDataResult shopDataResult = businessService.findBusinessDataWithIncomeTotalOrderByIncome(param);

            //TODO 4.加入开业日期
            if (CollectionUtil.isNotEmpty(shopDataResult.getList())) {
                for (Map<String, Object> map : shopDataResult.getList()) {
                    Integer shopId = Integer.parseInt(map.get("shopId").toString());
                    String openDay = shopMap.get(shopId);
                    map.put("openDay", openDay);
                }
            }

            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, shopDataResult);
        }
        List<Map<String, Object>> businessDataOrderByIncome2 = new ArrayList<>();
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome2);

    }

    /**
     * 查询指定日，指定门店的收入信息
     */
    @RequestMapping("/findShopsIncomeByTime")
    @ResponseBody
    public ResponseData findShopsIncomeByTime(HttpServletRequest request, ProDataViewParam param) throws ParseException {
        logger.info("营业分析-查询指定日指定门店的收入信息参数：{}", param.toString());

        //TODO 1.1日期参数处理-开始日期
        if (StringUtils.isBlank(param.getDate())) {
            return ResponseData.error(412, "请求失败，日期参数不能为空");
        }
        getShopIds(request, param);

        //门店为空时返回空数据
        if(CollectionUtil.isEmpty(param.getParamList())){
            List<Map<String, Object>> businessDataOrderByIncome2 = new ArrayList<>();
            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome2);
        }
        //TODO 1.获取门店id
        List<Map<String, Object>> shops = projectBusinessViewService.findShopsByParam(param);
        List<Integer> shopIdList = new ArrayList<>();
        Map<Integer, String> shopMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(shops)) {
            for (Map<String, Object> shop : shops) {
                Integer shopId = Integer.parseInt(shop.get("shopId").toString());
                shopIdList.add(shopId);
                shopMap.put(shopId, shop.get("openDay").toString());
            }
        }
        param.setParamList(shopIdList);

        if (CollectionUtil.isNotEmpty(shopIdList)) {
            //TODO 2.参数处理-月份日期处理

            param.setStartTime(param.getDate().trim() + " 04:00:00");
            param.setEndTime(DateUtil.get4OclockByDay(param.getDate().trim()));

            //TODO 3.获取查询结果
            //复用之前方法，补齐参数
            if (param.getLimit() == null) {
                param.setLimit(10000);
            }

            ShopDataResult shopDataResult = businessService.findBusinessDataWithIncomeTotalOrderByIncome(param);

            //TODO 4.加入开业日期
            if (CollectionUtil.isNotEmpty(shopDataResult.getList())) {
                for (Map<String, Object> map : shopDataResult.getList()) {
                    Integer shopId = Integer.parseInt(map.get("shopId").toString());
                    String openDay = shopMap.get(shopId);
                    map.put("openDay", openDay);
                }
            }

            return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, shopDataResult);
        }
        List<Map<String, Object>> businessDataOrderByIncome2 = new ArrayList<>();
        return ResponseData.success(200, ResponseData.DEFAULT_SUCCESS_MESSAGE, businessDataOrderByIncome2);

    }
}
